import {IterationOf} from '../Iteration/IterationOf'
import {Iteration} from '../Iteration/Iteration'
import {Next} from '../Iteration/Next'
import {Length} from './Length'
import {Pos} from '../Iteration/Pos'
import {Cast} from '../Any/Cast'
import {List} from './List'
import {Naked} from './_Internal'
import {Extends} from '../Any/Extends'
import {Append} from './Append'

/**
 * @hidden
 */
type __Zip<L extends List, L1 extends List, LN extends List = [], I extends Iteration = IterationOf<0>> = {
    0: __Zip<L, L1, Append<LN, [L[Pos<I>], L1[Pos<I>]]>, Next<I>>
    1: LN
}[Extends<Pos<I>, Length<L>>]

/**
 * @hidden
 */
export type _Zip<L extends List, L1 extends List> =
    __Zip<Naked<L>, L1> extends infer X
    ? Cast<X, List>
    : never

/**
 * Pair up the entries of `L` with `L1`
 * @param L to pair up
 * @param L1 to pair up with
 * @returns [[List]]
 * @example
 * ```ts
 * ```
 */
export type Zip<L extends List, L1 extends List> =
    L extends unknown
    ? L1 extends unknown
      ? _Zip<L, L1>
      : never
    : never
